


// 是否是 node 环境
const isNode = (typeof global === 'object');

let fs, path;
if (isNode) {
    // console.log('=========== this is node!');
    fs = require('fs');
    path = require('path');
}else{
    // console.log('=========== not node!');
}
let NodeUtils =  {
    /**
     * 删除 fullpath 如果是目录则直接连目录也一起删除
     * @param fullpath
     */
    rmFileOrDir(fullpath) {
        if (fs.existsSync(fullpath)) {
            let stats = fs.statSync(fullpath);
            if (stats.isDirectory()) {
                let files = fs.readdirSync(fullpath);
                files.forEach(f => {
                    let newFullpath = path.join(fullpath, f);
                    NodeUtils.rmFileOrDir(newFullpath);
                });
                fs.rmdirSync(fullpath);
            } else {
                // 是文件,直接删除
                fs.unlinkSync(fullpath);
            }
        }
    },

    /**
     * 创建目录
     * @param dirPath
     * @param recursive
     * @return {*}
     */
    mkdir(dirPath, recursive = true) {
        if (!fs.existsSync(dirPath)) {
            fs.mkdirSync(dirPath, {recursive: recursive});
        }
        return dirPath;
    },

    /**
     * 复制文件
     * @param srcFile
     * @param dstFile
     * @param sucCb {Function | null}
     */
    copy(srcFile, dstFile,sucCb) {
        if(!fs.existsSync(srcFile)){
            throw new Error(`srcFile:${srcFile} do not exist!`);
        }
        let dirpath = path.dirname(dstFile);
        this.mkdir(dirpath);

        let rs = fs.createReadStream(srcFile);
        let ws = fs.createWriteStream(dstFile);
        ws.on('finish',()=>{
            // 复制完毕
            if(sucCb){
                sucCb();
            }
        });
        rs.pipe(ws);
    },

    /**
     *  ArrayBuffer转为字符串，参数为ArrayBuffer对象
     * @param buf {ArrayBuffer}
     * @return {string}
     */
    ab2str(buf) {
        return String.fromCharCode.apply(null, new Uint16Array(buf));
    },

    /**
     * 字符串转为ArrayBuffer对象，参数为字符串.
     * 把字符串的每个字符都用一个 Uint16Array去存储,获得响应的二进制数据.
       解码的时候,也按照相对的方法解码即能得到二进制数据.
     * @param str
     * @return {ArrayBuffer}
     */
    str2ab(str) {
        let buf = new ArrayBuffer(str.length * 2); // 每个字符占用2个字节
        let bufView = new Uint16Array(buf);
        for (let i = 0, strLen = str.length; i < strLen; i++) {
            bufView[i] = str.charCodeAt(i);
        }
        return buf;
    },

    //
    /**
     *  buffer 和 arraybuffer 之间的相互转换
     * @param ab {ArrayBuffer}
     * @return {Buffer}
     */
    ab2b(ab) {
        let uint8Arr = new Uint8Array(ab);
        let buf = Buffer.alloc(uint8Arr.length);
        for (let i = 0, len = uint8Arr.length; i < len; ++i) {
            buf.writeUInt8(uint8Arr[i], i);
        }
        return buf;
    },

    /**
     *
     * @param buf {Buffer}
     * @return {ArrayBuffer}
     */
    b2ab(buf) {
        let arrbuf = new ArrayBuffer(buf.length);
        let uint8Arr = new Uint8Array(arrbuf);
        for (let i = 0, len = buf.length; i < len; ++i) {
            uint8Arr[i] = buf.readUInt8(i);
        }
        return arrbuf;
    },
};

export default NodeUtils;
